"""
适配器元数据系统

本模块定义了适配器的元数据系统，用于描述适配器的基本信息、配置、依赖等。
通过统一的元数据，系统可以更好地管理和展示适配器信息。

元数据包括：
1. 基本信息：名称、版本、作者、描述等
2. 配置参数：必需/可选参数、默认值等
3. 依赖信息：Python包依赖、API密钥要求等
4. 状态信息：是否启用、健康状态等

作者: 架构组
创建日期: 2025-10-06
"""

from enum import Enum
from typing import Dict, List, Any, Optional, Set
from dataclasses import dataclass, field
from datetime import datetime


# ==================== 适配器状态枚举 ====================

class AdapterStatus(str, Enum):
    """
    适配器状态枚举
    """
    
    ACTIVE = "active"              # 活跃（已启用且工作正常）
    INACTIVE = "inactive"          # 未启用
    DEGRADED = "degraded"          # 降级（部分功能不可用）
    ERROR = "error"                # 错误（不可用）
    MAINTENANCE = "maintenance"    # 维护中
    DEPRECATED = "deprecated"      # 已弃用


# ==================== 适配器分类枚举 ====================

class AdapterCategory(str, Enum):
    """
    适配器分类枚举
    """
    
    PRIMARY = "primary"            # 主要数据源（高质量、高可靠性）
    SECONDARY = "secondary"        # 次要数据源（备用）
    SPECIALIZED = "specialized"    # 专业数据源（特定用途）
    EXPERIMENTAL = "experimental"  # 实验性（测试中）
    DEPRECATED = "deprecated"      # 已弃用


# ==================== 配置参数数据类 ====================

@dataclass
class ConfigParameter:
    """
    配置参数定义
    
    描述适配器的一个配置参数。
    
    Attributes:
        name: 参数名称
        type: 参数类型（str, int, bool等）
        required: 是否必需
        default: 默认值
        description: 参数描述
        options: 可选值列表（如果有限制）
        sensitive: 是否敏感信息（如API密钥）
    """
    
    name: str
    type: str
    required: bool = False
    default: Any = None
    description: str = ""
    options: Optional[List[Any]] = None
    sensitive: bool = False
    
    def validate(self, value: Any) -> bool:
        """验证参数值是否有效"""
        # 检查类型（简单实现）
        if value is None:
            return not self.required
        
        # 检查选项（如果有限制）
        if self.options and value not in self.options:
            return False
        
        return True
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'name': self.name,
            'type': self.type,
            'required': self.required,
            'default': self.default,
            'description': self.description,
            'options': self.options,
            'sensitive': self.sensitive,
        }


# ==================== 适配器依赖数据类 ====================

@dataclass
class AdapterDependency:
    """
    适配器依赖定义
    
    描述适配器的外部依赖。
    
    Attributes:
        package: Python包名称
        version: 版本要求（如 ">=1.0.0"）
        optional: 是否可选
        purpose: 依赖用途说明
    """
    
    package: str
    version: str = ""
    optional: bool = False
    purpose: str = ""
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'package': self.package,
            'version': self.version,
            'optional': self.optional,
            'purpose': self.purpose,
        }


# ==================== 适配器元数据数据类 ====================

@dataclass
class AdapterMetadata:
    """
    适配器元数据
    
    描述适配器的完整元信息。
    
    Attributes:
        name: 适配器名称（唯一标识）
        display_name: 显示名称
        version: 版本号
        author: 作者
        description: 描述
        category: 分类
        status: 状态
        config_params: 配置参数列表
        dependencies: 依赖列表
        supported_markets: 支持的市场
        supported_data_types: 支持的数据类型
        documentation_url: 文档链接
        source_url: 源代码链接
        license: 许可证
        tags: 标签
        created_at: 创建时间
        updated_at: 更新时间
    """
    
    # 基本信息
    name: str
    display_name: str = ""
    version: str = "1.0.0"
    author: str = ""
    description: str = ""
    
    # 分类和状态
    category: AdapterCategory = AdapterCategory.SECONDARY
    status: AdapterStatus = AdapterStatus.ACTIVE
    
    # 配置和依赖
    config_params: List[ConfigParameter] = field(default_factory=list)
    dependencies: List[AdapterDependency] = field(default_factory=list)
    
    # 能力标签（简单字符串形式）
    supported_markets: List[str] = field(default_factory=list)
    supported_data_types: List[str] = field(default_factory=list)
    
    # 链接
    documentation_url: str = ""
    source_url: str = ""
    license: str = ""
    
    # 其他
    tags: List[str] = field(default_factory=list)
    metadata: Dict[str, Any] = field(default_factory=dict)
    
    # 时间戳
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    
    def __post_init__(self):
        """初始化后处理"""
        if not self.display_name:
            self.display_name = self.name.replace('_', ' ').title()
        
        if not self.created_at:
            self.created_at = datetime.now()
        
        if not self.updated_at:
            self.updated_at = datetime.now()
    
    def get_required_config(self) -> List[ConfigParameter]:
        """获取必需的配置参数"""
        return [p for p in self.config_params if p.required]
    
    def get_optional_config(self) -> List[ConfigParameter]:
        """获取可选的配置参数"""
        return [p for p in self.config_params if not p.required]
    
    def get_required_dependencies(self) -> List[AdapterDependency]:
        """获取必需的依赖"""
        return [d for d in self.dependencies if not d.optional]
    
    def get_optional_dependencies(self) -> List[AdapterDependency]:
        """获取可选的依赖"""
        return [d for d in self.dependencies if d.optional]
    
    def validate_config(self, config: Dict[str, Any]) -> tuple[bool, List[str]]:
        """
        验证配置是否有效
        
        Returns:
            (是否有效, 错误消息列表)
        """
        errors = []
        
        for param in self.config_params:
            value = config.get(param.name)
            
            if not param.validate(value):
                if param.required and value is None:
                    errors.append(f"Missing required parameter: {param.name}")
                elif param.options and value not in param.options:
                    errors.append(
                        f"Invalid value for {param.name}: {value}. "
                        f"Must be one of {param.options}"
                    )
        
        return len(errors) == 0, errors
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'name': self.name,
            'display_name': self.display_name,
            'version': self.version,
            'author': self.author,
            'description': self.description,
            'category': self.category.value,
            'status': self.status.value,
            'config_params': [p.to_dict() for p in self.config_params],
            'dependencies': [d.to_dict() for d in self.dependencies],
            'supported_markets': self.supported_markets,
            'supported_data_types': self.supported_data_types,
            'documentation_url': self.documentation_url,
            'source_url': self.source_url,
            'license': self.license,
            'tags': self.tags,
            'metadata': self.metadata,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'updated_at': self.updated_at.isoformat() if self.updated_at else None,
        }


# ==================== 元数据构建辅助函数 ====================

def create_tushare_metadata() -> AdapterMetadata:
    """创建Tushare适配器元数据"""
    return AdapterMetadata(
        name="tushare",
        display_name="Tushare Pro",
        version="1.0.0",
        author="Tushare",
        description="Tushare金融数据接口，提供A股、基金、期货等多种金融数据",
        category=AdapterCategory.PRIMARY,
        status=AdapterStatus.ACTIVE,
        config_params=[
            ConfigParameter(
                name="token",
                type="str",
                required=True,
                description="Tushare API Token",
                sensitive=True
            ),
            ConfigParameter(
                name="timeout",
                type="int",
                required=False,
                default=30,
                description="请求超时时间（秒）"
            ),
        ],
        dependencies=[
            AdapterDependency(
                package="tushare",
                version=">=1.2.0",
                optional=False,
                purpose="Tushare数据接口"
            ),
        ],
        supported_markets=["CN_A_SHARES", "CN_INDICES", "CN_FUNDS"],
        supported_data_types=["REALTIME_QUOTES", "HISTORICAL_KLINE", "FUNDAMENTAL_DATA"],
        documentation_url="https://tushare.pro/document/2",
        source_url="https://github.com/waditu/tushare",
        license="BSD-3-Clause",
        tags=["china", "stocks", "professional", "paid"],
    )


def create_akshare_metadata() -> AdapterMetadata:
    """创建AkShare适配器元数据"""
    return AdapterMetadata(
        name="akshare",
        display_name="AkShare",
        version="1.0.0",
        author="AkShare",
        description="AkShare开源金融数据接口，提供股票、基金、期货等多种免费数据",
        category=AdapterCategory.SECONDARY,
        status=AdapterStatus.ACTIVE,
        config_params=[
            ConfigParameter(
                name="timeout",
                type="int",
                required=False,
                default=30,
                description="请求超时时间（秒）"
            ),
            ConfigParameter(
                name="use_cache",
                type="bool",
                required=False,
                default=True,
                description="是否使用缓存"
            ),
        ],
        dependencies=[
            AdapterDependency(
                package="akshare",
                version=">=1.0.0",
                optional=False,
                purpose="AkShare数据接口"
            ),
        ],
        supported_markets=["CN_A_SHARES", "CN_INDICES", "HK_STOCKS", "US_STOCKS"],
        supported_data_types=["REALTIME_QUOTES", "HISTORICAL_KLINE", "NEWS"],
        documentation_url="https://akshare.akfamily.xyz/",
        source_url="https://github.com/akfamily/akshare",
        license="MIT",
        tags=["china", "stocks", "free", "open-source"],
    )


def create_yfinance_metadata() -> AdapterMetadata:
    """创建Yahoo Finance适配器元数据"""
    return AdapterMetadata(
        name="yfinance",
        display_name="Yahoo Finance",
        version="1.0.0",
        author="Yahoo",
        description="Yahoo Finance数据接口，提供全球股票、ETF、期货等数据",
        category=AdapterCategory.PRIMARY,
        status=AdapterStatus.ACTIVE,
        config_params=[
            ConfigParameter(
                name="timeout",
                type="int",
                required=False,
                default=30,
                description="请求超时时间（秒）"
            ),
        ],
        dependencies=[
            AdapterDependency(
                package="yfinance",
                version=">=0.2.0",
                optional=False,
                purpose="Yahoo Finance数据接口"
            ),
        ],
        supported_markets=["US_STOCKS", "US_INDICES", "US_ETF", "HK_STOCKS"],
        supported_data_types=["REALTIME_QUOTES", "HISTORICAL_KLINE", "COMPANY_INFO"],
        documentation_url="https://github.com/ranaroussi/yfinance",
        source_url="https://github.com/ranaroussi/yfinance",
        license="Apache-2.0",
        tags=["global", "stocks", "free", "open-source"],
    )

